<!--
 * @Author: rxn 1003312535@qq.com
 * @Date: 2024-07-05 15:25:53
 * @LastEditors: rxn 1003312535@qq.com
 * @LastEditTime: 2024-07-22 16:28:04
 * @FilePath: \vue3-progect\src\views\example\three\geometry\index.vue
 * @Description: 这是默认设置,请设置`customMade`, 打开koroFileHeader查看配置 进行设置: https://github.com/OBKoro1/koro1FileHeader/wiki/%E9%85%8D%E7%BD%AE
-->
<!--生成曲线几何体-->
<template>
	<div id="three_container"></div>
	<el-button class="downLoadBtn" ref="downLoadBtn" @click="saveFile"
		>下载</el-button
	>
</template>

<script setup>
import * as THREE from "three";
import { onMounted, ref } from "vue";
//-
import { AxesHelper } from "../case/helper/AxesHelper";
//-
import { initContainer } from "../js/init";
import { onResize } from "../case/helper/onResize.js";

let scene, renderer, camera;
onMounted(() => {
	let container = document.getElementById("three_container");
	let instances = initContainer(THREE, container);
	scene = instances.scene;
	renderer = instances.renderer;
	camera = instances.camera;
	AxesHelper(THREE, scene);
	onResize(container, renderer, camera);
	demo();
});
const demo = () => {
	/**
	 * 绘制圆
	 */
	const geometry = new THREE.BufferGeometry();
	const R = 100;
	const N = 50;
	const sp = (2 * Math.PI) / N;
	const arr = [];
	for (let i = 0; i < N; i++) {
		const angle = sp * i;
		const x = R * Math.cos(angle);
		const y = R * Math.sin(angle) + 50;
		arr.push(x, y, 0);
	}
	const vertices = new Float32Array(arr);
	const attribute = new THREE.BufferAttribute(vertices, 3);
	geometry.attributes.position = attribute;
	const material = new THREE.LineBasicMaterial({ color: 0xff0000 });
	const line = new THREE.LineLoop(geometry, material);
	scene.add(line);
	console.log(line);
	/**
	 * 绘制圆点
	 */
	const pointMaterial = new THREE.PointsMaterial({
		color: 0x00ff00,
		size: 2.0
	});
	const pointMesh = new THREE.Points(geometry, pointMaterial);
	scene.add(pointMesh);
	/**
	 * 几何体方法.setFromPoints()
	 */
	const pointsArr = [
		new THREE.Vector3(0, 0, 10),
		new THREE.Vector3(0, 100, 10),
		new THREE.Vector3(100, 100, 10),
		new THREE.Vector3(100, 0, 10)
	];
	const geometryPoint = new THREE.BufferGeometry();
	geometryPoint.setFromPoints(pointsArr);
	const geometryPointMesh = new THREE.Line(geometryPoint, material);
	scene.add(geometryPointMesh);
	/**
	 * 曲线Curve介绍
	 */
	/**
	 * 椭圆
	 * 1.定义
	 * 2.分段
	 * 3.赋值、几何体、材质、
	 * 4.添加显示
	 */
	const ellipse = new THREE.EllipseCurve(0, 0, 50, 150);
	const ellipsePointsArr = ellipse.getPoints(50);
	const ellipseGeometry = new THREE.BufferGeometry();
	ellipseGeometry.setFromPoints(ellipsePointsArr);
	const ellipseMesh = new THREE.Line(ellipseGeometry, material);
	scene.add(ellipseMesh);

	/**
	 * 三维向量Vector3创建一组顶点坐标
	 */
	const camullRomCurve3Arr = [
		new THREE.Vector3(-50, 20, 90),
		new THREE.Vector3(-10, 40, 40),
		new THREE.Vector3(0, 0, 0),
		new THREE.Vector3(60, -60, 0),
		new THREE.Vector3(70, 0, 80)
	];
	// 三维样条曲线
	const curve = new THREE.CatmullRomCurve3(camullRomCurve3Arr);
	const curvePointsArr = curve.getPoints(100);
	const geometry1 = new THREE.BufferGeometry();
	//读取坐标数据赋值给几何体顶点
	geometry1.setFromPoints(curvePointsArr);
	// 线材质
	const material1 = new THREE.LineBasicMaterial({
		color: 0x0000fff
	});
	// 线模型
	const line1 = new THREE.Line(geometry1, material1);
	scene.add(line1);
	//点
	const camullRomCurvePoints = new THREE.Points(geometry1, pointMaterial);
	scene.add(camullRomCurvePoints);

	/**
	 * 贝塞尔曲线
	 */
	// p1、p3是曲线起始点，p2是曲线的控制点
	const p1 = new THREE.Vector2(-80, 0);
	const p2 = new THREE.Vector2(20, 100);
	const p3 = new THREE.Vector2(80, 0);
	// 二维二次贝赛尔曲线
	const QuadraticBezierCurve = new THREE.QuadraticBezierCurve(p1, p2, p3);
	const QuadraticBezierCurveArr = QuadraticBezierCurve.getPoints(100); //曲线上获取点
	const geometry2 = new THREE.BufferGeometry();
	geometry2.setFromPoints(QuadraticBezierCurveArr); //读取坐标数据赋值给几何体顶点
	// 线
	const line2 = new THREE.Line(geometry2, material);
	scene.add(line2);
	//点
	const QuadraticBezierCurvePoints = new THREE.Points(geometry2, pointMaterial);
	scene.add(QuadraticBezierCurvePoints);

	/**
	 *
	 */
	const geometry3 = new THREE.BufferGeometry();
	geometry3.setFromPoints([p1, p2, p3]);
	const material3 = new THREE.PointsMaterial({
		color: 0xff00ff,
		size: 4
	});
	const point3 = new THREE.Points(geometry3, material3);
	scene.add(point3);
	const line3 = new THREE.Line(geometry3, material3);
	scene.add(line3);
	/**
	 * 三维二次贝赛尔曲线QuadraticBezierCurve3
	 */
	// p1、p2、p3表示三个点坐标
	const p41 = new THREE.Vector3(-80, 0, 0);
	const p42 = new THREE.Vector3(20, 100, 0);
	const p43 = new THREE.Vector3(80, 0, 100);
	// 三维二次贝赛尔曲线
	const curve4 = new THREE.QuadraticBezierCurve3(p41, p42, p43);
	const curveArr4 = curve4.getPoints(20);
	const geometry4 = new THREE.BufferGeometry();
	geometry4.setFromPoints(curveArr4);
	// 线
	const line4 = new THREE.Line(geometry4, material);
	scene.add(line4);
	//点
	const point4 = new THREE.Points(geometry4, pointMaterial);
	scene.add(point4);
};

/**
 * 下载图片
 */
const downLoadBtn = ref(null);
const saveFile = () => {
	console.log(downLoadBtn, "downLoadBtn");
	const link = document.createElement("a");
	const canvas = renderer.domElement;
	link.href = canvas.toDataURL("image/png");
	link.download = "threejs.png";
	link.click();
};
</script>

<style lang="less" scoped>
#three_container {
	height: 100%;
}
.downLoadBtn {
	position: absolute;
	right: 0;
	top: 10px;
	z-index: 99;
}
</style>
